package cn.zbacm.api.img.service;

import cn.zbacm.api.img.StorageException;
import com.google.gson.Gson;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;

/** @author 16639 */
@Slf4j
@Service
public class ImgService {
  @Value("${qiniu.oss.url}")
  private String qiniuUrl;

  @Value("${qiniu.access-key}")
  private String accessKey;

  @Value("${qiniu.secret-key}")
  private String secretKey;

  @Value("${qiniu.oss.bucket-name}")
  private String bucketName;

  private Auth auth;

  private UploadManager uploadManager;

  private Gson gson;

  @PostConstruct
  void init() {
    auth = Auth.create(accessKey, secretKey);
    Configuration configuration = new Configuration(Region.huanan());
    uploadManager = new UploadManager(configuration);
    gson = new Gson();
  }

  public String upload(MultipartFile file, String dir) {
    // TODO: 检查文件是否是音视频，以及文件大小
    String fileName =
        System.currentTimeMillis()
            + StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
    try {
      if (fileName.contains("..")) {
        throw new StorageException("Sorry! Filename contains invalid path sequence " + fileName);
      }
      String upToken = auth.uploadToken(bucketName);
      log.info("uplod token " + auth + upToken);
      Response response =
          uploadManager.put(file.getInputStream(), dir + fileName, upToken, null, null);

      DefaultPutRet putRet = gson.fromJson(response.bodyString(), DefaultPutRet.class);
      if (!putRet.key.equals(dir + fileName)) {
        return null;
      }
      log.info("returnUrl=" + qiniuUrl.concat("/").concat(putRet.key));
      // 上传成功后的url
      return qiniuUrl.concat("/").concat(putRet.key);
    } catch (IOException e) {
      throw new StorageException("Could not store file " + fileName + ". Please try again!", e);
    }
  }

  public String upload(File file, String dir) {

    String fileName = System.currentTimeMillis() + StringUtils.cleanPath(file.getName());
    try {
      if (fileName.contains("..")) {
        throw new StorageException("Sorry! Filename contains invalid path sequence " + fileName);
      }
      String upToken = auth.uploadToken(bucketName);
      String localFilePath = file.getAbsolutePath();

      Response response = uploadManager.put(localFilePath, dir + fileName, upToken);

      DefaultPutRet putRet = gson.fromJson(response.bodyString(), DefaultPutRet.class);

      if (!putRet.key.equals(dir + fileName)) {
        return null;
      }
      log.info("returnUrl=" + qiniuUrl.concat("/").concat(putRet.key));
      // 上传成功后的url
      return qiniuUrl.concat("/").concat(putRet.key);
    } catch (IOException e) {
      throw new StorageException("Could not store file " + fileName + ". Please try again!", e);
    }
  }

  public String upload(InputStream inputStream, String dir, String filename) {
    // TODO: 检查文件是否是音视频，以及文件大小
    String fileName = System.currentTimeMillis() + StringUtils.cleanPath(filename);
    try {
      if (fileName.contains("..")) {
        throw new StorageException("Sorry! Filename contains invalid path sequence " + fileName);
      }
      String upToken = auth.uploadToken(bucketName);
      Response response = uploadManager.put(inputStream, dir + fileName, upToken, null, null);

      DefaultPutRet putRet = gson.fromJson(response.bodyString(), DefaultPutRet.class);
      if (!putRet.key.equals(dir + fileName)) {
        return null;
      }
      log.info("returnUrl=" + qiniuUrl.concat("/").concat(putRet.key));
      // 上传成功后的url
      return qiniuUrl.concat("/").concat(putRet.key);
    } catch (IOException e) {
      throw new StorageException("Could not store file " + fileName + ". Please try again!", e);
    }
  }
}
